package com.windo.helloBubble.objects;

import java.util.LinkedList;
import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;

public class Bubbles extends View{
	
	//varialbes
    private float boundaryX = 300;
    private float boundaryY = 300; //this one should be get automaticly
    private float originXY = 0;
    private final static int MAX_BUBBLE_NUM = 10;
    private final static float HIT_OFFSET = 25;
    private final static float SPEED_LIMIT = 2;
    private final static float DEFAULT_RADIUS = 30;
    private enum WallHit{VERTICAL_HIT, HORIZONTAL_HIT, NO_HIT};
    private final Paint myPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint txtPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Thread animator;
    private static final int RED = 0xffFF8080;
    private static final int BLUE = 0xff8080FF;
    private static final int CYAN = 0xff80ffff;
    private static final int GREEN = 0xff80ff80;
    final Random myRandom = new Random();
    private LinkedList <Bubble> bubbleList;
    private String DSMM = "DSMM-Tag";
    
    public Bubbles(Context context) {
    	 super(context);
    	 
    	 bubbleList = new LinkedList<Bubble>();
    	 addBubble(originXY + DEFAULT_RADIUS, originXY + DEFAULT_RADIUS);
    	 /* hard code part **/
         myPaint.setColor(RED);
         txtPaint.setTextSize(10);
         txtPaint.setColor(BLUE);
	}
    
    @Override
    protected void onDraw(Canvas canvas) {
    	//Log.v("DSMMM", "drawing the bubbles");
        super.onDraw(canvas);
        boundaryX = canvas.getWidth();
        boundaryY = canvas.getHeight();
        drawBubbles(canvas);
    }
    
    private void drawBubbles(Canvas canvas){
    	for(int i = 0; i < bubbleList.size(); i ++){
    		Bubble currBubble = bubbleList.get(i);
    		canvas.drawCircle(currBubble.centerX, currBubble.centerY, 
    				currBubble.bubbleR, myPaint);
    		//also paint the text on it
    		canvas.drawText(currBubble.ballName, 
    				currBubble.centerX, currBubble.centerY, txtPaint);
    	}  	
    }
    
    public void addBubble(float x, float y){
    	if(bubbleList.size() < MAX_BUBBLE_NUM){
    		//when touch, add a bubble
    		Bubble newBubble = new Bubble(x, y, SPEED_LIMIT, DEFAULT_RADIUS, Integer.toString((bubbleList.size() - 1)));
    		bubbleList.add(newBubble);
    	}	
    }
    
	public void moveBubbles(){
		Bubble currBubble = null;
		checkBubblesHitsAndBounce();
		for(int i = 0; i < bubbleList.size(); i ++){
			//MOVE EVERY BUBBLE
			currBubble = bubbleList.get(i);
			currBubble.moveBallPosition();
		}
		invalidate();
	}
	public boolean removeBubble(float x, float y){
		Bubble currBubble = null;
		Bubble removeBubble = new Bubble(x, y, 0, DEFAULT_RADIUS, null);
		int removeMark = -1;
		for(int i = 0; i < bubbleList.size(); i ++){
			//MOVE EVERY BUBBLE
			currBubble = bubbleList.get(i);
			if( get2BubbleDistance(currBubble, removeBubble) < HIT_OFFSET){
				Log.v(DSMM, "Going to remove a bubble");
				removeMark = i;
			}
		}
		if(removeMark != -1){
			bubbleList.remove(removeMark);
			return true;
		}else{
			return false;
		}
	}
	public void checkBubblesHitsAndBounce(){
		Bubble currBubble = null;
		Bubble checkBubble = null;
		//Log.v("DSMM", "CHECKING BALL HITS!");
		for(int i = 0; i < bubbleList.size(); i ++){
			//checking each currBubble
			currBubble = bubbleList.get(i);
			for(int j = 0; j < bubbleList.size(); j ++){
				if(i != j){ //skip the current bubble
					checkBubble = bubbleList.get(j);
					if(isBubbleHit(currBubble, checkBubble)){
						Log.v("DSMM", "HIT THE OTHER BALL!");
						//bounce the bubbles
						float tempSpeedX, tempSpeedY;
						tempSpeedX = currBubble.speedX;
						tempSpeedY = currBubble.speedY;
						currBubble.setSpeed(checkBubble.speedX, checkBubble.speedY);
						checkBubble.setSpeed(tempSpeedX, tempSpeedY);
						currBubble.moveBallPosition(); //** need to move it right away, otherwise will be switch back
						checkBubble.moveBallPosition();
					}
				}
			}//checking hiting the boundary
			WallHit isWallHit = isWallHit(currBubble);
			if(isWallHit != WallHit.NO_HIT){
				if(isWallHit == WallHit.HORIZONTAL_HIT){
					currBubble.flipX();
				}else if(isWallHit == WallHit.VERTICAL_HIT){
					currBubble.flipY();
				}
			}	
		}
	}
	private float get2BubbleDistance(Bubble b1, Bubble b2){
		float A, B;
		A = b1.centerX - b2.centerX;
		B = b1.centerY - b2.centerY;
		return (float) Math.sqrt( A*A + B*B );
	}
	
	private boolean isBubbleHit(Bubble b1, Bubble b2){	
		if(get2BubbleDistance(b1, b2) < (b1.bubbleR + b2.bubbleR)){
			return true;
		}else{
			return false;
		}
	}
	private WallHit isWallHit(Bubble b1){
		if((b1.centerX + b1.bubbleR) > boundaryX || (b1.centerX - b1.bubbleR) < originXY){
			return WallHit.HORIZONTAL_HIT;
		}else if((b1.centerY + b1.bubbleR) > boundaryY || (b1.centerY - b1.bubbleR) < originXY ){
			return WallHit.VERTICAL_HIT;
		}
		return WallHit.NO_HIT;
	}

}
